package com.hang.ad.handler;

import com.hang.ad.dump.table.*;
import com.hang.ad.index.DataTable;
import com.hang.ad.index.IndexAware;
import com.hang.ad.index.adplan.AdPlanIndex;
import com.hang.ad.index.adplan.AdPlanObject;
import com.hang.ad.index.adunit.AdUnitIndex;
import com.hang.ad.index.adunit.AdUnitObject;
import com.hang.ad.index.creative.CreativeIndex;
import com.hang.ad.index.creative.CreativeObject;
import com.hang.ad.index.creativeUnit.CreativeUnitIndex;
import com.hang.ad.index.creativeUnit.CreativeUnitObject;
import com.hang.ad.index.district.UnitDistrictIndex;
import com.hang.ad.index.interest.UnitInterestIndex;
import com.hang.ad.index.keyword.UnitKeywordIndex;
import com.hang.ad.mysql.constant.OpType;
import com.hang.ad.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

@Slf4j
public class AdLevelDataHandler {
    public static void handleLevel2(AdPlanTable adPlanTable, OpType type){
        AdPlanObject adPlanObject = new AdPlanObject(adPlanTable.getId(),
                                                     adPlanTable.getUserId(),
                                                     adPlanTable.getPlanStatus(),
                                                     adPlanTable.getStartDate(),
                                                     adPlanTable.getEndDate());
        handleBinlogEvent(DataTable.of(AdPlanIndex.class), adPlanObject.getPlanId(),adPlanObject,type);
    }

    public static void handleLevel2(AdCreativeTable adCreativeTable, OpType type){
        CreativeObject creativeObject = new CreativeObject(
                adCreativeTable.getAdId(),
                adCreativeTable.getName(),
                adCreativeTable.getType(),
                adCreativeTable.getMaterialType(),
                adCreativeTable.getHeight(),
                adCreativeTable.getWidth(),
                adCreativeTable.getAuditStatus(),
                adCreativeTable.getAdUrl());
        handleBinlogEvent(DataTable.of(CreativeIndex.class), creativeObject.getAdId(), creativeObject, type);
    }

    public static void handleLevel3(AdUnitTable adUnitTable, OpType type){
        AdPlanObject adPlanObject = DataTable.of(AdPlanIndex.class).get(adUnitTable.getPlanId());
        if (adPlanObject == null){
            log.error("handleLevel3 found adPlanObject error");
            return;
        }
        AdUnitObject adUnitObject = new AdUnitObject(adUnitTable.getUnitId(),
                adUnitTable.getUnitStatus(),
                adUnitTable.getPositionType(),
                adUnitTable.getPlanId(),
                adPlanObject);
        handleBinlogEvent(DataTable.of(AdUnitIndex.class), adUnitObject.getUnitId(), adUnitObject, type);
    }

    public static void handleLevel3(AdCreativeUnitTable adCreativeUnitTable, OpType type){
        if (type == OpType.UPDATE){
            log.error("creativeUnitIndex not support update");
            return;
        }

        AdUnitObject adUnitObject = DataTable.of(AdUnitIndex.class).get(adCreativeUnitTable.getUnitId());
        CreativeObject creativeObject = DataTable.of(CreativeIndex.class).get(adCreativeUnitTable.getAdId());
        if (adUnitObject == null || creativeObject == null){
            log.error("handleLevel3 found adUnitObject or creativeObject error");
            return;
        }

        CreativeUnitObject creativeUnitObject = new CreativeUnitObject(adCreativeUnitTable.getAdId(),
                adCreativeUnitTable.getUnitId());
        handleBinlogEvent(DataTable.of(CreativeUnitIndex.class),
                CommonUtils.stringConcat(creativeUnitObject.getAdId().toString(), creativeUnitObject.getUnitId().toString()),
                creativeUnitObject, type);

    }

    public static void handleLevel4(AdUnitDistrictTable adUnitDistrictTable, OpType type){
        if (type == OpType.UPDATE){
            log.error("adUnitDistrictTable not support update");
            return;
        }
        AdUnitObject adUnitObject = DataTable.of(AdUnitIndex.class).get(adUnitDistrictTable.getUnitId());
        if (adUnitObject == null){
            log.error("handleLevel4 found adUnitObject error");
            return;
        }
        String key = CommonUtils.stringConcat(adUnitDistrictTable.getProvince(), adUnitDistrictTable.getCity());
        Set<Long> value = new HashSet<>(Collections.singleton(adUnitDistrictTable.getUnitId()));
        handleBinlogEvent(DataTable.of(UnitDistrictIndex.class), key, value, type);
    }

    public static void handleLevel4(AdUnitItTable adUnitItTable, OpType type){
        if (type == OpType.UPDATE){
            log.error("adUnitItTable not support update");
            return;
        }
        AdUnitObject adUnitObject = DataTable.of(AdUnitIndex.class).get(adUnitItTable.getUnitId());
        if (adUnitObject == null){
            log.error("handleLevel4 found adUnitObject error");
            return;
        }
        Set<Long> value = new HashSet<>(Collections.singleton(adUnitItTable.getUnitId()));
        handleBinlogEvent(DataTable.of(UnitInterestIndex.class), adUnitItTable.getItTag(), value, type);
    }

    public static void handleLevel4(AdUnitKeywordTable adUnitKeywordTable, OpType type){
        if (type == OpType.UPDATE){
            log.error("adUnitKeywordTable not support update");
            return;
        }
        AdUnitObject adUnitObject = DataTable.of(AdUnitIndex.class).get(adUnitKeywordTable.getUnitId());
        if (adUnitObject == null){
            log.error("handleLevel4 found adUnitObject error");
            return;
        }
        Set<Long> value = new HashSet<>(Collections.singleton(adUnitKeywordTable.getUnitId()));
        handleBinlogEvent(DataTable.of(UnitKeywordIndex.class), adUnitKeywordTable.getKeyword(), value, type);
    }

    private static <K, V> void handleBinlogEvent(
            IndexAware<K,V> index,
            K key,
            V value,
            OpType type){
        switch (type){
            case ADD:
                index.add(key,value);
                break;
            case UPDATE:
                index.update(key, value);
                break;
            case DELETE:
                index.delete(key, value);
                break;
            default:
                break;
        }
    }
}
